﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "IElement.h"

namespace gcmp
{
    class IDocument;
    class ElementId;
    class IElementFilter;
    class Box3d;
    class ILinkModelViewProxy;
    class ILinkDocumentType;

    /// \brief 链接模型对象接口
    class GCMP_MODEL_INTERFACE_EXPORT ILinkDocumentElement : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::ILinkDocumentElement, gcmp::IElement);
    public:

        /// \brief 创建链接模型对象
        ///
        /// \param pHostDocument 链接模型对象所属文档
        /// \param typeId 链接文档类型id
        /// \return ILinkDocumentElement* 创建好的链接模型对象
        static ILinkDocumentElement* Create(IDocument* pHostDocument, ElementId typeId);

        /// \brief 获取链接文档
        /// \return IDocument* 链接文档指针
        virtual const IDocument* GetLinkDocument() const = 0;

        /// \brief 获取链接文档
        /// \return IDocument* 链接文档指针
        virtual IDocument* GetLinkDocument() = 0;

        /// \brief 获取链接文档类型对象
        /// \return ILinkDocumentType* 链接文档类型对象指针
        virtual const ILinkDocumentType* GetLinkDocumentType() const = 0;

        /// \brief 获取该链接模型对象对应的所有链接模型代理对象的ElementId
        /// \return std::vector<ElementId>& 该链接模型对象对应的所有链接模型代理对象的ElementId
        virtual const std::vector<ElementId>& GetElementProxyIds() const = 0;

        /// \brief 获取该链接模型对象对应的所有链接视图代理对象的ElementId
        /// \return std::vector<ElementId>& 该链接模型对象对应的所有链接视图代理对象的ElementId
        virtual const std::vector<ElementId>& GetModelViewProxyIds() const = 0;

        /// \brief 获取链接模型对象中对应当前主体视图的代理对象
        /// \return 视图的代理对象
        virtual ILinkModelViewProxy* GetLinkModelViewProxy(const ElementId& hostModelViewId) = 0;

        /// \brief 获取链接模型对象中对应当前主体视图的代理对象
        /// \return 视图的代理对象
        virtual const ILinkModelViewProxy* GetLinkModelViewProxy(const ElementId& hostModelViewId) const = 0;

        /// \brief 获取链接模型对象相对于原点放置的转换矩阵
        /// \return Matrix4d 转换矩阵
        virtual Matrix4d GetTransform() const = 0;

        /// \brief 获取包围盒
        /// \return Box3d 包围盒
        virtual Box3d GetBoundingBox() const = 0;

        /// \brief 根据被链接文档的对象改变状态，新增、删除、更新代理对象
        /// \param added 新增的对象
        /// \param added 删除的对象
        /// \param added 更新的对象
        /// \return 更新成功-true;失败-false
        virtual bool SyncProxyElements(
            const std::vector<ElementId> & added,
            const std::vector<ElementId> & deleted,
            const std::vector<ElementId> & updated
        ) = 0;

        /// \brief 获取被链接的对象和代理对象的映射关系
        /// \return 返回映射关系
        virtual const std::unordered_map<ElementId, ElementId, ElementIdHash>& GetLinkIdsToProxyIds() const = 0;

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };
}
